import socket  # 导入 socket 模块
from threading import Thread
import time
import json

import pika
from queue import Queue

import operator # 用于比较数据的不同 适用任何数据
# https://blog.csdn.net/linxinfa/article/details/104001443
# 比较元素 https://blog.csdn.net/qq_24918869/article/details/52175886
# queueu https://www.cnblogs.com/lincappu/p/12890761.html

from test4 import C_queueServer

#基本FIFO队列  先进先出 FIFO即First in First Out,先进先出
FIFO = Queue(maxsize=0) #maxsize设置队列中，数据上限，小于或等于0则不限制，容器中大于这个数则阻塞，直到队列中的数据被消掉
FIFO_sand = Queue(maxsize=0) #maxsize设置队列中，数据上限，小于或等于0则不限制，容器中大于这个数则阻塞，直到队列中的数据被消掉

#消息处理函数，执行完成才说明接收完成，此时才可以接收下一条，串行
def dongcallbackfun(v1,v2,v3,bodyx):
    print("C_queueServer:回调函数 接收到了数据",bodyx)
    FIFO.put(bodyx)
    print("C_queueServer", FIFO.qsize(), FIFO.queue)



class C_deviceServer:
    socket_server = None
    socket_server_ADDRESS = None
    socket_serverlisten_Num = None
    socket_server_client_message = {"message":None, "connet":False, "thread":None} # 用于存放客户端的数据，客户端的信息，连接连接状态
    socket_server_client_list = []
    def __init__(self):
        self.listen_Num = 0 # 最大监听数
        self.socket_server_ADDRESS = ('0.0.0.0', 8080)  # 绑定地址

    def init(self):
        """
        初始化服务端
        """
        g_socket_server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)  
        g_socket_server.bind(self.socket_server_ADDRESS)
        g_socket_server.listen(self.listen_Num)  # 最大等待数（有很多人理解为最大连接数，其实是错误的）
        print("C_deviceServer:初始化服务端")
        return g_socket_server
    def accept_client(self, obj):
        """
        接收新连接
        """
        print("C_deviceServer:打开监听准备连接")
        while True:
            client, info = obj.accept()  # 阻塞，等待客户端连接
            print("C_deviceServer:新创建了一个客户端")
            '''
            通过阻塞等待，表示已经接收到了一个新的TCP连接，那么可以向下创建新的接收和发送数据
            '''
            
            
            thread = Thread(target = self.message_handle_rev, args=(client, info)) # 设备发送数据给django
            # 设置成守护线程
            thread.setDaemon(True)
            thread.start()
            socket_server_client_message = {"message":client,  # 用于存放客户端的数据，客户端的信息，连接连接状态
                                            "info":info, 
                                            "connet":True, 
                                            "thread":thread}
            self.socket_server_client_list.append(socket_server_client_message)
            print(self.socket_server_client_list)
            
            # 给每个客户端创建一个独立的线程进行管理
            thread = Thread(target = self.message_handle_sand, args=(client, info)) # django发送数据给设备 
            # 设置成守护线程 
            thread.setDaemon(True)
            thread.start()

    def message_handle_rev(self, client, info):
        """
        消息处理
        """
        obj_queueServer = C_queueServer()
        obj_queueServer.queue_init_sand()
        print("新的客户端连接", client)
        while True:
            bytes = client.recv(1024)
            msg = bytes.decode(encoding='utf8')
            if(len(bytes)):
                obj_queueServer.queue_sand()
                print("C_deviceServer:", info,"收到了数据：",msg, "发送数据到Django中")
            else:
                print("tcp断开了")
                #remove_client(client)
                for client_message in self.socket_server_client_list:
                    print("info", client_message["info"], info)
                    if(client_message["info"] == info):
                        client_message["connet"] = False
                        break
                break
        
    def message_handle_sand(self, client, info):
        """
        消息处理
        """
        client.sendall("C_deviceServer: connect server successfully!".encode(encoding='utf8'))
        print("新的客户端连接", client, FIFO.queue)
        while True:
            try:
                lists = FIFO.get(block=True, timeout=2) # 阻塞方式接收获取数据
                print(lists)
                print("C_deviceServer:tcp设备的单独服务器接收到了从Dango传来的fifo", FIFO.queue)
                client.sendall("I have get message!".encode(encoding='utf8'))
            except:
                print("C_deviceServer", info,  "还没有数据要发送给设备")
                for client_message in self.socket_server_client_list:
                    if(operator.eq(client_message["info"], info) == True ):
                        print("C_deviceServer: 找到了设备")
                        if(client_message["connet"] == False):
                            print("C_deviceServer: 设备被关闭，清理线程")
                            return
                        else:
                            print("C_deviceServer: 设备还在连接")                       

if __name__ == '__main__':
    aClass1 = C_queueServer()
    aClass1.queue_init_rev()
    aClass1.queue_rev_Run(dongcallbackfun)

    aClass = C_deviceServer()
    g_socket_server = aClass.init()
    aClass.accept_client(g_socket_server)

    while(1):
        time.sleep(1)